package com.netdisk.service.impl;

import com.netdisk.dto.request.file.DeleteDTO;
import com.netdisk.dto.request.file.RenameDTO;
import com.netdisk.dto.request.file.UploadDTO;
import com.netdisk.dto.response.file.FileDTO;
import com.netdisk.entity.File;
import com.netdisk.entity.Trash;
import com.netdisk.exception.BusinessException;
import com.netdisk.mapper.FileMapper;
import com.netdisk.mapper.TrashMapper;
import com.netdisk.mapper.UserMapper;
import com.netdisk.service.FileService;
import com.netdisk.service.UserActivityService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;
import com.netdisk.entity.User;

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

@Service
public class FileServiceImpl implements FileService {
   @Value("${file.upload-dir}")
   private String uploadDir;

   @Autowired
   private FileMapper fileMapper;
   @Autowired
   private TrashMapper trashMapper;
   @Autowired
   private UserMapper userMapper;
   @Autowired
   private UserActivityService userActivityService;
   /**
    * 上传文件
    * @param uploadDTO
    * @return
    */
   public FileDTO uploadFile(@RequestBody UploadDTO uploadDTO) throws IOException {
      FileDTO fileDTO = new FileDTO();
      File file = new File();
      MultipartFile uploadFile = uploadDTO.getFile();
      Integer userId = uploadDTO.getUserId();
      User user = userMapper.findById(userId);
      if (user == null) {
         throw new BusinessException("用户不存在");
      }

      // 处理文件存储路径
      Path uploadPath = Paths.get(uploadDir).toAbsolutePath().normalize();

      // 确保目录存在
      if (!Files.exists(uploadPath)) {
         Files.createDirectories(uploadPath);
      }

      // 处理文件名
      String originalFileName = StringUtils.cleanPath(uploadFile.getOriginalFilename());
      String fileName = System.currentTimeMillis() + "_" + originalFileName;

      // 保存文件
      Path targetPath = uploadPath.resolve(fileName);
      Files.copy(uploadFile.getInputStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);

      file.setName(originalFileName);
      file.setSize(uploadFile.getSize());
      file.setType(uploadFile.getContentType());
      file.setUserId(userId);
      file.setPath(targetPath.toString());
      fileMapper.insert(file);

      BeanUtils.copyProperties(file, fileDTO);
      userActivityService.insertActivity(file, "上传文件", "upload");

      return fileDTO;
   }

   /**
    * 下载文件
    * @param userId
    * @param fileId
    * @return
    */
   public ResponseEntity<Resource> downloadFile(Integer userId, Integer fileId) throws Exception {
      File file = fileMapper.getFileById(userId, fileId);
      Path path = Paths.get(file.getPath());
      Resource resource = new UrlResource(path.toUri());

      return ResponseEntity.ok()
              .header(HttpHeaders.CONTENT_TYPE, "application/octet-stream")
              .header(HttpHeaders.CONTENT_DISPOSITION,
                      "attachment; filename=\""+file.getName()+"\"")
              .body(resource); // 二进制数据直接传输

   }

   /**
    * 获取文件总数
    * @param userId
    * @return
    */
   public Integer getFileCountById(Integer userId){
      Integer fileCount = fileMapper.getFileCountById(userId);
      Integer trashCount = trashMapper.getTrashCountById(userId);
      return fileCount - trashCount;
   }

   /**
    * 获取文件列表
    * @param userId
    * @return
    */
   public List<FileDTO> getFileListById(Integer userId) {
      List<File> fileList = fileMapper.getFileListById(userId);
      List<FileDTO> fileDTOList = new ArrayList<>();
      for (File f : fileList) {
         if (f != null && f.getDeletedAt() == null) {
            FileDTO fileDTO = new FileDTO();
            BeanUtils.copyProperties(f, fileDTO);
            fileDTOList.add(fileDTO);
         }
      }
      return fileDTOList;
   }

   /**
    * 删除文件
    * @param deleteDTO
    */
   public void deleteFile(@RequestBody DeleteDTO deleteDTO){
      Integer id = deleteDTO.getId();
      Integer userId = deleteDTO.getUserId();
      File file = fileMapper.getFileById(userId,id);
      Trash trash = new Trash();
      if (file != null && file.getDeletedAt() == null) {
         trash.setUserId(userId);
         trash.setFileId(id);
         trashMapper.insert(trash);
         fileMapper.deleteFile(id);
         userActivityService.insertActivity(file, "删除文件", "delete");
      }
      else throw new BusinessException("文件不存在");
   }

   /**
    * 重命名文件
    * @param renameDTO
    * @return
    */
   public FileDTO renameFile(@RequestBody RenameDTO renameDTO){
      Integer id = renameDTO.getId();
      Integer userId = renameDTO.getUserId();
      String newName = renameDTO.getNewName();
      File file = fileMapper.getFileById(userId,id);
      FileDTO fileDTO = new FileDTO();
      if(file != null && file.getDeletedAt() == null) {
         /*确保返回修改后的名称*/
         file.setName(newName);
         fileMapper.renameFile(id,newName);
         BeanUtils.copyProperties(file,fileDTO);
         userActivityService.insertActivity(file, "重命名文件", "rename");
      }
      else throw new BusinessException("文件不存在");
      return fileDTO;
   }


}
